package com.degon.hsyl.faceviewdemo;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.renderscript.Sampler;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import java.util.logging.LogRecord;

public class FaceView2 extends View {

    //圆弧半径
    private int radius = 40;

    //圆弧画笔宽度
    private float paintWidth = 15;

    //笑脸状态（一个脸，两个眼睛）
    private final int smileStatus = 0;

    //加载状态（合并眼睛，旋转）
    private final int loadingStatus = 1;

    //合并完成，转一圈
    private final int circleStatus = 2;

    //转圈完成，吐出眼睛
    private final int splitStatus = 3;

    //当前状态
    private int currentStatus = smileStatus;

    //笑脸画笔
    private Paint facePaint;

    //眼睛画笔
    private Paint eyePaint;

    //笑脸开始角度
    private float startAngle;

    //笑脸弧度
    private float swipeAngle;

    //左侧眼睛起点坐标
    private float leftEyeX = 0;

    //左侧眼睛起点y轴坐标
    private float leftEyeY = 0;

    //右侧眼睛起点x坐标
    private float rightEyeX = 0;

    //右侧眼睛起点y坐标
    private float rightEyeY = 0;

    //一开始默认状态笑脸转圈动画
    private ValueAnimator faceLoadingAnimator;

    //吞并完成后，自转一圈动画
    private ValueAnimator circleAnimator;

    //faceLoadingAnimator动画进度值
    private float faceValue;

    //circleAnimator动画进度值
    private float circleValue;

    //记录开始自转一圈的起始角度
    private float circleStartAngle;

    //吐出眼睛的角度
    private float splitAngle;

    private float initStartAngle;

    //眼睛起始角度
    private float eyeStartAngle;

    public FaceView2(Context context) {
        this(context, null);
    }

    public FaceView2(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @SuppressLint("Recycle")
    public FaceView2(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        //自定义属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FaceView2, defStyleAttr, 0);

        initStartAngle = typedArray.getFloat(R.styleable.FaceView2_startAngle, 0);
        swipeAngle = typedArray.getFloat(R.styleable.FaceView2_swipeAngle, 180);
        splitAngle = typedArray.getFloat(R.styleable.FaceView2_splitAngle, 260);

        typedArray.recycle();

        startAngle = initStartAngle;
        eyeStartAngle = initStartAngle;
        eyeStartAngle += startAngle;

        initEyes();

        initPaint();

        initAnimator();
    }

    private void initPaint() {
        facePaint = new Paint();
        facePaint.setStrokeWidth(paintWidth);
        facePaint.setColor(Color.RED);
        facePaint.setAntiAlias(true);
        facePaint.setStyle(Paint.Style.STROKE);
        facePaint.setStrokeCap(Paint.Cap.ROUND);

        eyePaint = new Paint();
        eyePaint.setStrokeWidth(paintWidth);
        eyePaint.setColor(Color.RED);
        eyePaint.setAntiAlias(true);
        eyePaint.setStyle(Paint.Style.STROKE);
        eyePaint.setStrokeCap(Paint.Cap.ROUND);
    }

    /**
     * 初始化眼睛坐标
     */
    private void initEyes() {
        //默认两个眼睛坐标位置 角度转弧度
        leftEyeX = (float) (-radius * Math.cos(eyeStartAngle * Math.PI / 180));
        leftEyeY = (float) (-radius * Math.sin(eyeStartAngle * Math.PI / 180));
        rightEyeX = (float) (radius * Math.cos(eyeStartAngle * Math.PI / 180));
        rightEyeY = (float) (-radius * Math.sin(eyeStartAngle * Math.PI / 180));
    }

    private Handler mHandler = new Handler(new Handler.Callback() {
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case 1:
                    //启动一开始笑脸转圈动画，并且开始合并眼睛
                    currentStatus = loadingStatus;
                    faceLoadingAnimator.start();
                    break;
                case 2:
                    //暂停眼睛和笑脸动画
                    currentStatus = circleStatus;
                    faceLoadingAnimator.pause();
                    //启动笑脸自转一圈动画
                    circleAnimator.start();
                    break;
                case 3:
                    //恢复笑脸转圈动画，并且开始分离眼睛
                    currentStatus = splitStatus;
                    circleAnimator.cancel();
                    faceLoadingAnimator.resume();
                    invalidate();
                    break;
            }
            return false;
        }
    });

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画布移到中间
        canvas.translate(getWidth() / 2, getHeight() / 2);

        switch (currentStatus) {
            case smileStatus:
                //起始角度为0
                startAngle = initStartAngle;

                //画起始笑脸
                canvas.drawArc(-radius, -radius, radius, radius, startAngle, swipeAngle, false, facePaint);

                //重置起始眼睛坐标
                initEyes();

                //画起始眼睛
                canvas.drawPoint(leftEyeX, leftEyeY, eyePaint);
                canvas.drawPoint(rightEyeX, rightEyeY, eyePaint);

                //更改状态，进行笑脸合并眼睛
                mHandler.sendEmptyMessage(1);
                break;
            //合并状态
            case loadingStatus:
                //记录时刻的旋转角度
                startAngle = faceValue * 360;

                //追上右边眼睛
                if (startAngle >= 120 + startAngle / 2) {
                    canvas.drawArc(-radius, -radius, radius, radius, startAngle, swipeAngle, false, facePaint);

                    //开始自转一圈
                    mHandler.sendEmptyMessage(2);

                    //此时记录自转一圈起始的角度
                    circleStartAngle = 120 + startAngle / 2;
                } else {
                    //追眼睛的过程
                    canvas.drawArc(-radius, -radius, radius, radius, startAngle, swipeAngle, false, facePaint);
                }

                //画左边眼睛，旋转的角度设置为笑脸旋转角度的一半，这样笑脸才能追上眼睛
                leftEyeX = (float) (-radius * Math.cos((60 + startAngle / 2) * Math.PI / 180));
                leftEyeY = (float) (-radius * Math.sin((60 + startAngle / 2) * Math.PI / 180));
                canvas.drawPoint(leftEyeX, leftEyeY, eyePaint);

                //画右边眼睛，旋转的角度设置为笑脸旋转角度的一半，这样笑脸才能追上眼睛
                rightEyeX = (float) (radius + Math.cos((60 - startAngle / 2) * Math.PI / 180));
                rightEyeY = (float) (-radius + Math.sin((60 - startAngle / 2) * Math.PI / 180));
                canvas.drawPoint(rightEyeX, rightEyeY, eyePaint);
                break;
            case circleStatus:
                //自转一圈状态 circleValue * 360为旋转角度
                canvas.drawArc(-radius, -radius, radius, radius, circleStartAngle + circleValue * 360, swipeAngle, false, facePaint);
                break;
            case splitStatus:
                //笑脸眼睛分离状态
                startAngle = faceValue * 360;
                //判断当前笑脸的起点是否已经走过了260°（吐出眼睛的角度，角度可以任意设置）
                if (startAngle >= splitAngle) {
                    //画左边眼睛，旋转的角度设置为笑脸旋转角度的2倍，这样眼睛才能快于笑脸旋转速度
                    leftEyeX = (float) (-radius + Math.cos((eyeStartAngle + startAngle * 2) * Math.PI / 180));
                    leftEyeY = (float) (-radius + Math.sin((eyeStartAngle + startAngle * 2) * Math.PI / 180));
                    canvas.drawPoint(leftEyeX, leftEyeY, eyePaint);

                    //画右边眼睛 ，旋转的角度设置为笑脸旋转角度的2倍，这样眼睛才能快于笑脸旋转速度
                    rightEyeX = (float) (radius * Math.cos((eyeStartAngle - startAngle * 2) * Math.PI / 180));
                    rightEyeY = (float) (-radius * Math.sin((eyeStartAngle - startAngle * 2) * Math.PI / 180));
                    canvas.drawPoint(rightEyeX, rightEyeY, eyePaint);
                }
                //画笑脸
                canvas.drawArc(-radius, -radius, radius, radius, startAngle, swipeAngle,
                        false, facePaint);
                break;
        }
    }

    /**
     * 初始化动画
     */
    private void initAnimator(){

        faceLoadingAnimator = ValueAnimator.ofFloat(0, 1).setDuration(1000);
        faceLoadingAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        faceLoadingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                faceValue = (float) animation.getAnimatedValue();
                invalidate();
            }
        });

        //动画延迟500ms启动
        faceLoadingAnimator.setStartDelay(500);

        faceLoadingAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                //恢复初始状态
                currentStatus = smileStatus;
            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }

            @Override
            public void onAnimationStart(Animator animation) {

            }
        });

        circleAnimator = ValueAnimator.ofFloat(0, 1).setDuration(1000);

        circleAnimator.setInterpolator(new LinearInterpolator());

        circleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                circleValue = (float) animation.getAnimatedValue();
                invalidate();
            }
        });

        circleAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                mHandler.sendEmptyMessage(3);
            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }

            @Override
            public void onAnimationStart(Animator animation) {

            }
        });

    }
}
